package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.WeMediaConstants;
import com.heima.model.admin.dtos.NewsAuthDto;
import com.heima.model.admin.dtos.NewsWithAuthorName;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.service.WmNewsTaskService;
import com.heima.wemedia.service.WmUserService;
import com.heima.wemedia.util.WmMediaThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @Author bo.li
 * @Date 2023/2/1 11:05
 * @Version 1.0
 */
@Slf4j
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsAutoScanService autoScanService;
    @Autowired
    private WmNewsTaskService taskService;

    @Override
    public ResponseResult pageList(WmNewsPageReqDto dto) {
        //参数校验
        dto.checkParam();
        //分页对象构造
        IPage page = new Page(dto.getPage(), dto.getSize());
        //构造查询条件
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        //状态筛选
        wrapper.eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus());
        //开始结束时间
        if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null) {
            wrapper.between(WmNews::getCreatedTime, dto.getBeginPubDate(), dto.getEndPubDate());
        }
        //频道
        wrapper.eq(dto.getChannelId() != null, WmNews::getChannelId, dto.getChannelId());
        //关键字
        wrapper.like(!StringUtils.isEmpty(dto.getKeyword()), WmNews::getTitle, dto.getKeyword());
        //用户
        wrapper.eq(WmNews::getUserId, WmMediaThreadLocalUtil.getUser().getId());

        wrapper.orderByDesc(WmNews::getCreatedTime);
        //查询结果
        page(page, wrapper);
        //封装结果
        ResponseResult result = new PageResponseResult(dto.getPage(), (int) page.getSize(), (int) page.getTotal());
        result.setData(page.getRecords());
        return result;
    }

    @Override
    public ResponseResult submit(WmNewsDto newsDto) {
        //参数校验
        if (StringUtils.isEmpty(newsDto.getTitle()) || StringUtils.isEmpty(newsDto.getContent())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //文章保存（含修改）
        WmNews wmNews = saveOrUpdateNews(newsDto);
        //判断是否为草稿
        if (newsDto.getStatus() == WmNews.Status.NORMAL.getCode()) {
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
        //关联正文中图片和素材的关系
        //获取正文中所有的图片
        List<String> images = getAllImages(newsDto.getContent());
        saveRelations(images, wmNews.getId(), WeMediaConstants.REFERENCE_CONTENT);

        //关联封面图片和素材的关系
        saveRelationForCover(images, wmNews, newsDto);

        if (newsDto.getPublishTime() != null) {
            taskService.addTask(wmNews);
        } else {
            //内容安全检测
            autoScanService.autoScan(wmNews);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //人工审核列表
    @Override
    public PageResponseResult listVO(NewsAuthDto dto) {
        if (dto.getPage() == null || dto.getSize() == null) {
            return (PageResponseResult) ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(dto.getStatus())) {
            queryWrapper.eq(WmNews::getStatus, dto.getStatus());
        }
        if (!StringUtils.isEmpty(dto.getTitle())) {
            queryWrapper.like(WmNews::getTitle, dto.getTitle());
        }
        IPage page = new Page(dto.getPage(), dto.getSize());
        this.page(page, queryWrapper);
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), (int) page.getSize(), (int) page.getTotal());
        //塞入作者名称
        List<NewsWithAuthorName> responseList = new ArrayList<>();
        NewsWithAuthorName newsWithAuthorName = new NewsWithAuthorName();
        if (page.getRecords().size() == 0){
            ResponseResult.errorResult(AppHttpCodeEnum. DATA_NOT_EXIST);
        }
        List records = page.getRecords();
        for (Object record : records) {
            WmNews wmNews = JSON.parseObject(JSON.toJSONString(record), WmNews.class);
            BeanUtils.copyProperties(wmNews,newsWithAuthorName);
            newsWithAuthorName.setAuthorName(wmUserService.getById(wmNews.getUserId()).getName());
            responseList.add(newsWithAuthorName);
        }
        pageResponseResult.setData(responseList);
        return pageResponseResult;
    }

    //人工审核页面详情
    @Autowired
    private WmUserService wmUserService;
    @Override
    public ResponseResult getOneVO(Integer id) {
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        WmNews wmNews = this.getById(id);
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //查找自媒体作者名称
        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        NewsWithAuthorName responseDto = new NewsWithAuthorName();
        BeanUtils.copyProperties(wmNews,responseDto);
        responseDto.setAuthorName(wmUser.getName());
        return ResponseResult.okResult(responseDto);
    }

    //审核失败
    @Override
    public ResponseResult authFail(NewsAuthDto dto) {
        if (dto.getId() == null || dto.getStatus() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        WmNews wmNews = this.getById(dto.getId());
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (wmNews.getStatus() != WmNews.Status.ADMIN_AUTH.getCode()){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        wmNews.setStatus(WmNews.Status.FAIL.getCode());
        if (!StringUtils.isEmpty(dto.getMsg())) {
            wmNews.setReason(dto.getMsg());
        }
        wmNews.setReason(dto.getMsg());
        this.updateById(wmNews);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //审核成功
    @Override
    public ResponseResult authPass(NewsAuthDto dto) {
        if (dto.getId() == null || dto.getStatus() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        WmNews wmNews = this.getById(dto.getId());
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (wmNews.getStatus() != WmNews.Status.ADMIN_AUTH.getCode()){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        wmNews.setStatus(WmNews.Status.ADMIN_SUCCESS.getCode());
        this.updateById(wmNews);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 处理封面图片和素材关系
     *
     * @param contentImages
     * @param wmNews
     */
    private void saveRelationForCover(List<String> contentImages, WmNews wmNews, WmNewsDto newDto) {
        List<String> images = newDto.getImages();
        //如果封面类型是自动
        if (newDto.getType() == WeMediaConstants.TYPE_AUTO) {
            int size = contentImages.size();
            if (size >= 3) {
                wmNews.setType(WeMediaConstants.TYPE_MANY_PIC);
                images = contentImages.stream().limit(3).collect(Collectors.toList());
            } else if (size >= 1 && size < 3) {
                wmNews.setType(WeMediaConstants.TYPE_SIGNAL_PIC);
                images = contentImages.stream().limit(1).collect(Collectors.toList());
            } else {
                wmNews.setType(WeMediaConstants.TYPE_NO_PIC);
            }
            if (!CollectionUtils.isEmpty(images)) {
                wmNews.setImages(StringUtils.collectionToCommaDelimitedString(images));
            }
            updateById(wmNews);
        }
        if (!CollectionUtils.isEmpty(images)) {
            saveRelations(images, wmNews.getId(), WeMediaConstants.REFERENCE_COVER);
        }
    }

    /**
     * 保存正文图片和素材的关系
     *
     * @param images
     * @param newsId
     */
    private void saveRelations(List<String> images, Integer newsId, short type) {
        if (CollectionUtils.isEmpty(images)) {
            return;
        }
        //查询所有素材ID
        LambdaQueryWrapper<WmMaterial> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.in(WmMaterial::getUrl, images);
        List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(queryWrapper);

        List<Integer> materialIds = wmMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());

        wmNewsMaterialMapper.saveAll(materialIds, newsId, type);
    }

    /**
     * 获取正文中所有的图片
     *
     * @param content
     * @return
     */
    private List<String> getAllImages(String content) {
        List<String> images = new ArrayList<>();
        List<Map> imageList = JSON.parseArray(content, Map.class);
        for (Map map : imageList) {
            String type = map.get("type").toString();
            String value = map.get("value").toString();
            if ("image".equals(type)) {
                images.add(value);
            }
        }
        return images;
    }


    /**
     * 保存或者修改文章
     * 修改文章的时候需要先删除素材关联关系
     *
     * @param newsDto
     */
    private WmNews saveOrUpdateNews(WmNewsDto newsDto) {
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(newsDto, wmNews);
        //图片处理
        if (!CollectionUtils.isEmpty(newsDto.getImages())) {
            String imageStr = StringUtils.collectionToCommaDelimitedString(newsDto.getImages());
            wmNews.setImages(imageStr);
        }

        if (newsDto.getType() == WeMediaConstants.TYPE_AUTO) {
            wmNews.setType(null);
        }

        wmNews.setUserId(WmMediaThreadLocalUtil.getUser().getId());
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());

        if (newsDto.getId() == null) {
            save(wmNews);
        } else {
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, newsDto.getId()));
            //删除关联关系
            updateById(wmNews);
        }
        return wmNews;
    }
}